//
// Created by LiuYou on 2021/5/19.
//

#include <cstdlib>
#include <unistd.h>
#include <cstdio>
#include <pthread.h>
#include <cstring>


#define LEFT            30000000
#define RIGHT           30000200
#define THR_NUM         (RIGHT - LEFT + 1)

static void* thr_prime(void* pVoid);

/**
 * @brief 对 ThreadTest06-IPCTest02-prime-number.cpp 程序的改进使之能够正确运行。
 *
 * 
 * 并这个程序中学习信号量(semaphore)。
 * 信号量的学习我放在了 MySemaphore目录下。
 *
 */
int main() {

    pthread_t tid[THR_NUM];

    for (int i = LEFT; i <= RIGHT; ++i) {
        // TODO 注意: 这里产生竞争的原因是: 201个指针指向了同一个地址。 &i。
//        int err = pthread_create(tid + (i - LEFT), nullptr, thr_prime, &i);

        // TODO 注意: 改进
        int* pInt = new int(i);
        int err = pthread_create(tid + (i - LEFT), nullptr, thr_prime, pInt);
        if (err) {
            std::fprintf(stderr, "pthread_create(): %s\n", std::strerror(err));
            std::exit(1);
        }
    }
    for (int i = LEFT; i <= RIGHT; ++i) {
        pthread_join(tid[i - LEFT], nullptr);
    }


    std::exit(0);
}

static void* thr_prime(void* pVoid) {
    int mark{1};

    int i = *((int*) pVoid);
    // Cannot delete expression with pointer-to-'void' type 'void '
    // 无法删除带有指向“void”类型“void”的指针的表达式
    delete (int*) pVoid;

    // TODO 注意: 在C++中下面这条语句是错误的。
//    int i = (int) pVoid;

    for (int j = 2; j < i / 2; ++j) {
        if (i % j == 0) {
            mark = 0;
            break;
        }
    }
    if (mark == 1) {
        std::fprintf(stdout, "%d is prime number.\n", i);
    }

    pthread_exit(nullptr);
}